package com.wyw.function.learning.demo9;

import com.wyw.function.learning.common.Discount;
import com.wyw.function.learning.common.ExchangeService;
import com.wyw.function.learning.common.Quote;
import com.wyw.function.learning.common.Shop;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Stream;

/**
 * @Title   响应CompletableFuture的completion
 * @Description
 * @Author Mr Wu yewen.wu.china@gmail.com
 * Update History:
 * Author        Time            Content
 */
public class DemoClient26 {

    static final List<Shop> shops =
            Arrays.asList(
                    new Shop("wyw"),
                    new Shop("hello"),
                    new Shop("one"),
                    new Shop("two")
            );

    private static final Random r = new Random();

    private static void randomDelay() {
        int delay = 500 + r.nextInt(2000);
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static final ExchangeService exchangeService = new ExchangeService();

    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        CompletableFuture[] futures = findPrices("wyw")
//                .map(f -> f.thenAccept(System.out::println))
                .map(f -> f.thenAccept(s -> System.out.println(s + "(done in " + (System.currentTimeMillis() - start) + ":ms)")))// 打印每个执行事件
                .toArray(size -> new CompletableFuture[size]);
        CompletableFuture.allOf(futures).join();
        System.out.println("(all done in " + (System.currentTimeMillis() - start) + ":ms)");
    }

    public static Stream<CompletableFuture<String>> findPrices(String product) {
        ExecutorService ex = Executors.newCachedThreadPool();
        return shops.stream()
                .map(shop -> CompletableFuture.supplyAsync(
                        () -> shop.getPrice(product), ex
                ))
                .map(future -> future.thenApply(Quote::parse))
                .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync(
                        () -> Discount.applyDiscount(quote), ex
                )));
    }

}
